package com.sg.common.empty.core;

import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ning.http.client.Request;
import com.sg.common.empty.service.CfgService;
import com.sg.common.login.entity.Member;
import com.sg.common.login.entity.Org;
import com.sg.common.login.entity.OrgMember;
import com.sg.common.login.entity.Role;
import com.sg.common.utils.CollUtil;
import com.sg.common.utils.Constant;
import com.sg.common.utils.DateTimeUtils;
import com.sg.common.utils.ReUtils;
import com.sg.common.utils.UUIDGenerator;

public class FilterVal {

	private Logger logger = LoggerFactory.getLogger(getClass());

	public static FilterVal init(String val) {
		FilterVal res = new FilterVal();
		res.val = val;
		return res;
	}

	public static FilterVal init(String val, CfgService service) {
		FilterVal res = new FilterVal();
		res.val = val;
		res.service = service;
		return res;
	}

	String val;
	CfgService service;

	/**
	 * 针对不同的参数值，给出对应的结果集 用于filter数据过滤、增加页面中的默认数据 TODO 测试反射调用service查询值的能力
	 * 
	 * @param val
	 * @param service
	 * @return
	 * @throws ClassNotFoundException
	 */
	public Object get() {
		Object res = val;
		if (val.startsWith(":")) {
			if (val.equals(":currentOrgAndUnderIds")) {
				// res = currentOrgAndUnderIds(baseDao);
				// } else if (val.equals(":currentOrgAndUnder")) {
				// res = currentOrgAndUnder(baseDao);
			} else if (val.equals(":currentMemberId")) {
				res = findCurrentMemberId();
			} else if (val.equals(":currentMember")) {
				res = findCurrentMember();
			} else if (val.equals(":currentMemberCode")) {
				res = findCurrentMemberCode();
				// } else if (val.equals(":currentCompSingle")) {
				// res = findCurrentCompSingle();
				// } else if (val.equals(":currentCompSingleId")) {
				// res = findCurrentCompSingleId();
			} else if (val.equals(":currentDate")) {
				res = DateTimeUtils
						.formatDate(new Timestamp(System.currentTimeMillis()),
								"yyyy-MM-dd");
			} else if (val.equals(":currentTime")) {
				res = DateTimeUtils.formatDate(
						new Timestamp(System.currentTimeMillis()),
						"yyyy-MM-dd HH:mm");
			} else if (val.equals(":iCanSeePersons")) {
				res = findICanSeePersons();
			} else if (val.equals(":iCanSeeOrgs")) {
				res = findICanSeeOrgs();
			} else {
				Class<?> clazz;
				try {
					clazz = Class.forName(val.substring(1));
					FilterCus ca = (FilterCus) clazz.newInstance();
					ca.setService(service);
					res = ca.get();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					logger.info(e.getMessage());
				}
			}
		}
		return res;
	}

	public Object get2() {
		Object res = val;
		if (val.equals("currentOrgAndUnderIds")) {
		} else if (val.equals("currentMemberId")) {
			res = findCurrentMemberId();
		} else if (val.equals("currentMember")) {
			res = findCurrentMember();
		} else if (val.equals("currentMemberCode")) {
			res = findCurrentMemberCode();
		} else if (val.equals("currentDate")) {
			res = DateTimeUtils.formatDate(
					new Timestamp(System.currentTimeMillis()), "yyyy-MM-dd");
		} else if (val.equals("currentTime")) {
			res = DateTimeUtils.formatDate(
					new Timestamp(System.currentTimeMillis()),
					"yyyy-MM-dd HH:mm");
		} else if (val.equals("iCanSeePersons")) {
			res = findICanSeePersons();
		} else if (val.equals("iCanSeeOrgs")) {
			res = findICanSeeOrgs();
		}else if (val.equals("sys32Id")) {
			res = new UUIDGenerator().generate().toString();
		}else if (val.equals("depId")){
			res = findMyDepOrg().getId();
		}else if (val.equals("workShopId")){
			res = findMyWorkShop().getId();
		}
		return res;
	}

	public String findCurrentMemberId() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		Member member = (Member) request.getSession().getAttribute(
				Constant.SESSION_MEMBER);
		if (member != null)
			return member.getId();
		return "";
	}

	public String findCurrentMemberCode() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		Member member = (Member) request.getSession().getAttribute(
				Constant.SESSION_MEMBER);
		return member.getCode();
	}

	public Object findCurrentMember() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		Member member = (Member) request.getSession().getAttribute(
				Constant.SESSION_MEMBER);
		return member;
	}
	
	/**
	 * 查找我的部门ID(用于培训台账中新增培训计划/实际时保存部门ID,因TRI001角色需要看到所有部门中心的培训记录,查看培训列表时
	 * 需将“我的部门ID”信息清空，导致新增的培训计划部门ID为空----针对TRI001角色SESSION_MYDEPORG为空的情况,重新找部门ID)
	 * @return
	 */
	public Org findMyDepOrg(){
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
//		return (String)request.getSession().getAttribute(Constant.SESSION_MYDEPORG);
		List<String> myRoles = (List<String>) request.getSession()
				.getAttribute(Constant.SESSION_MYROLES_CODE);
		Boolean needReset = false;
		if (CollUtil.isNotEmpty(myRoles)) {
			for (String myRole : myRoles) {
				String TRI001 = "TRI001";
				if (StringUtils.equals(myRole, TRI001)) {
					needReset = true;
					break;
					}
				}
		}
		if(needReset){
			Member member = (Member) request.getSession().getAttribute(Constant.SESSION_MEMBER);
			Org myDirectOrg = findMyOffiOrg(member);
			if(myDirectOrg!=null){
				Org myDepOrg = findParentOrgByLeve(myDirectOrg, 1);
				return myDepOrg;
			}else{
				return null;
			}
		}else{
			return (Org)request.getSession().getAttribute(Constant.SESSION_MYDEPORG);
		}
		
	}
	
	/**
	 *  	“我的车间”,作为培训计划与培训实际的隐藏属性,用于限制仅可以修改/审核本车间的培训计划,修改本车间的培训实际
	 * @return
	 */
	public Org findMyWorkShop(){
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		return (Org)request.getSession().getAttribute(Constant.SESSION_MYWORKSHOPORG);
	}
	
	/**
	 * 查找我可以看到的卡片所属人
	 * 
	 * @return
	 */
	public String findICanSeePersons() {
		String res = "";
		List<Member> mList = new ArrayList<Member>();
		boolean canSeeAll = false;
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		Member member = (Member) request.getSession().getAttribute(
				Constant.SESSION_MEMBER);
		// TODO 用于处理是否为办事员组
		// 通过我的组织来找对应的角色 ROLEORG
		List<Org> myOrgs = (List<Org>) request.getSession().getAttribute(
				Constant.SESSION_MYORGS_INDIRECT);

		for (Org o : myOrgs) {
			if (StringUtils.equals(o.getOrge(), "tck01")) {
				canSeeAll = true;
				break;
			}
			if (StringUtils.equals(o.getAtt1(), "1")
					&& StringUtils.equals(o.getOrge(), "1200"))
			// &&StringUtils.equals(o.getWs6(),"1")
			{

				Org parent = o.getParent();
				if (parent != null) {
					List<Org> allOrgs = new ArrayList<Org>();
					try {

						findChild(allOrgs, parent, service);

						mList = findMemberByOrgs(allOrgs, service);

					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

			}
		}
		if (canSeeAll) {
			return "";
		} else {
			if (mList.size() == 0)
				mList.add(member);
			for (Member m : mList) {
				if (StringUtils.isEmpty(res))
					res = "'" + m.getId() + "'";
				else
					res = res + ",'" + m.getId() + "'";
			}
			res = "(" + res + ")";
			return res;
		}
	}

	private void findChild(List<Org> allOrgs, Org parent, CfgService service)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {

		allOrgs.add(parent);
		List<Object> orgs = findByParent(parent, service);

		for (Object o : orgs) {

			findChild(allOrgs, (Org) o, service);
		}
	}

	private List<Object> findByParent(Object p, CfgService service)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		Class<? extends Object> clazz = p.getClass();
		DetachedCriteria dc = DetachedCriteria.forClass(clazz);
		// Field declaredField = clazz.getDeclaredField("id");
		// String pid = (String) declaredField.get(p);
		String pid = ReUtils.getStr(p, "id");
		if (!StringUtils.isNotEmpty(pid)) {
			dc.add(Restrictions.isNull("parent"));
		} else {
			dc.add(Restrictions.eq("parent", p));
		}
		dc.add(Restrictions.eq("delfg", "0"));
		List<Object> pl = service.find(dc);

		return pl;
	}

	/**
	 * 查找我可以看到的卡片所属组织
	 * 
	 * @return
	 */
	public String findICanSeeOrgs() {
		String res = "";
		List<Org> allChildOrgs = new ArrayList<Org>();
		boolean canSeeAll = false;
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		Member member = (Member) session.getAttribute(Constant.SESSION_MEMBER);
		// TODO 用于处理是否为办事员组
		// 通过我的组织来找对应的角色 ROLEORG
		List<Org> myOrgs = (List<Org>) session
				.getAttribute(Constant.SESSION_MYORGS_INDIRECT);

		List<Role> myRoles = (List<Role>) request.getSession().getAttribute(
				Constant.SESSION_MYROLES);
		for (Role r : myRoles) {
			if (StringUtils.equals(r.getRole(), "admin")
					|| StringUtils.equals(r.getRole(), "cardRjb")) {
				canSeeAll = true;
				break;
			}
		}

		for (Org o : myOrgs) {
			// 安保部、票务、财务部可以看到所以卡片
			if (StringUtils.equals(o.getCode(), "tck10010")
					|| StringUtils.equals(o.getCode(), "tck10020")
					|| StringUtils.equals(o.getCode(), "tck10040")) {
				canSeeAll = true;
				break;
			}
			if (StringUtils.equals(o.getAtt1(), "1")
					&& StringUtils.equals(o.getOrge(), "1200")) {
				allChildOrgs = (List<Org>) session
						.getAttribute(Constant.SESSION_MANAGE_ORGS_BSY);
			}
		}
		if (canSeeAll) {
			return "";
		} else {
			for (Org o : allChildOrgs) {
				if (StringUtils.isEmpty(res))
					res = "'" + o.getId() + "'";
				else
					res = res + ",'" + o.getId() + "'";
			}
			if (StringUtils.isEmpty(res))
				res = "('')";
			else
				res = "(" + res + ")";
			return res;
		}
	}

	private List<Member> findMemberByOrgs(List<Org> Orgs, CfgService service)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		List<Member> res = new ArrayList<Member>();
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.add(Restrictions.in("org", Orgs)).add(Restrictions.eq("delfg", "0"));
		List<OrgMember> omlist = service.find(dc);
		for (OrgMember om : omlist) {

			res.add(om.getMember());
		}
		return res;
	}

	public String dftValue(String dftvalue) {
		String res = null;
		String replace = dftvalue.replace(":", "");
		if ("currentDate".equals(replace)) {
			res = DateTimeUtils.formatDate(
					new Timestamp(System.currentTimeMillis()), "yyyy-MM-dd");
		}
		return res;
	}
	

	/**
	 * 找到某人的内部组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findMyOffiOrg(Member m) {
		Org res = null;
		String[] orges = { "1000", "1300" };
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.createAlias("org", "org");
		dc.add(Restrictions.eq("member", m))
				.add(Restrictions.in("org.orge", orges))
				.add(Restrictions.eq("delfg", "0"))
				.add(Restrictions.eq("enable", "1"));
		OrgMember om = service.findBean(dc);
		if (om != null) {
			res = om.getOrg();
		}
		return res;
	}
	
	/**
	 * 找到某人的固定层级的内部组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findParentOrgByLeve(Org org, int leve) {
		Org res = null;
		int orgleve = Integer.valueOf(org.getOrglv());
		if (orgleve == leve) {
			res = org;
		} else {
			if (orgleve > leve)
				res = findParentOrgByLeve(org.getParent(), leve);
		}
		return res;
	}
	
}
